package com.qcrud.tookit;

import com.qcrud.exception.QcrudException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public final class ClassUtils {

    /**
     * <p>
     * 根据指定的 class ， 实例化一个对象，根据构造参数来实例化
     * </p>
     * <p>
     * 在 java9 及其之后的版本 Class.newInstance() 方法已被废弃
     * </p>
     *
     * @param clazz 需要实例化的对象
     * @param <T>   类型，由输入类型决定
     * @return 返回新的实例
     */
    public static <T> T newInstance(Class<T> clazz) {
        try {
            Constructor<T> constructor = clazz.getDeclaredConstructor();
            constructor.setAccessible(true);
            return constructor.newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new QcrudException("newInstance error: " + clazz, e);
        }
    }

    /**
     * 返回类型泛型的类型
     *
     * @param type {@link Type}
     * @return {@link Type[]}
     */
    public static Type[] getActualTypeArguments(Type type) {
        return ParameterizedType.class.cast(type).getActualTypeArguments();
    }

    /**
     * Type 类型转为 Class
     *
     * @param type {@link Type}
     * @return {@link Class}
     */
    public static Class getClass(Type type) {
        try {
            return Class.forName(type.getTypeName());
        } catch (ClassNotFoundException e) {
            throw new QcrudException(e);
        }
    }
}
